package com.bdhub;

import com.alibaba.fastjson.JSON;
import com.bdhub.common.MessageType;
import com.bdhub.handld.ClientBootstrap;
import com.bdhub.im.server.protobuf.MessageProtobuf.CMsg;
import com.bdhub.im.server.protobuf.MessageProtobuf.CMsgHead;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

/**
 * 消息发送超时定时器
 * @author lp
 *
 */
public class TimeoutTimer {
	private int num = 0;
	private Timer timer = null;
	private String mid;
	private int type;
	private MyTask tmt = null;
	private CMsg message;

	// private Map<String, TimeoutTimer> msgMap = null;
	private ClientBootstrap bootstrap;
	private static long lastOutTime = 0;
	private static int unitCount = 0;


	public TimeoutTimer(ClientBootstrap bootstrap, CMsg msg) {
		this.bootstrap = bootstrap;
		// msgMap = map;
		this.mid = msg.getHead().getMid();
		this.type = msg.getHead().getType();
		timer = new Timer();
		tmt = new MyTask();
		long time = bootstrap.getSendFreq();
		timer.schedule(tmt, time, time);
		this.message = msg;
	}

	public void cancel() {
		if (tmt != null) {
			tmt.cancel();
			tmt = null;
		}
		if (timer != null) {
			timer.cancel();
			timer = null;
		}

	}
	public CMsg getMessage()
	{
		return message;
	}
	/**
	 * 获取要重新发送的消息对象
	 * @return
	 */
	private CMsg getSendMessage(){
		//如果是登录消息，重新生成新的登录消息
		if(this.message.getHead().getType()== MessageType.LOGIN_REQ.value()){
		 return bootstrap.buildLoginMsg();
		}else{
			return this.message;
		}
	}
	/**
	 * 发送消息
	 */
	public void sendMessage(){
		bootstrap.sendMsg(getSendMessage());
	}

	private class MyTask extends TimerTask {
		@Override
		public void run() {
			// 判断imlib是否已经关闭
			if (bootstrap.isClose()) {
				bootstrap.getMessageTimeOutManager().removeAndStop(mid);
				return;
			}
			try {
				//定时器被调用次数
				num += 1;
				// 发送失败,启动重连
				if (num >= bootstrap.getSendTime()) {
					try {
						// 发送失败，发消息通知应用层
						UUID uuid = UUID.randomUUID();
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("mid", mid);
						map.put("type", type);
						map.put("status", "-1");
						String strjson = JSON.toJSONString(map);
						CMsgHead.Builder head = CMsgHead.newBuilder();
						head.setType(3003);
						head.setMid(uuid.toString());
						head.setComments(strjson);

						CMsg.Builder msg = CMsg.newBuilder();
						msg.setHead(head);

						bootstrap.getDispatcher().receiveMsg(msg.build());

						map.clear();
						map = null;

					} finally {
                        bootstrap.getMessageTimeOutManager().removeAndStop(mid);
						if (checkResetConnect()) {
							// 触发重连
							bootstrap.resetConnect();
						}
					}
				} else {
					sendMessage();
				}

			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private boolean checkResetConnect() {
		try {
			// 重置单位时间内的消息超时重连次数
			if (System.currentTimeMillis() - lastOutTime > 30 * 1000) {
				unitCount = 0;
			}
			// 半分钟之内，只允许触发3次消息发送超时重连，登录消息除外
			if (unitCount < 3 || type == MessageType.LOGIN_REQ.value()) {
				lastOutTime = System.currentTimeMillis();
				unitCount++;
				return true;
			}
			return false;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return false;

	}
	
	
}
